/**
 * <p>文件名:		FileHelper.java</p>
 * <p>版权:		CopyrightTag</p>
 * <p>公司:		CompanyTag</p>
 * @author		周华彬(zhouhuabin@ctfo.com)
 */

package com.caits.lbs.framework.utils;



import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;

import org.apache.log4j.Logger;

import com.caits.lbs.framework.log.CommonLogFactory;

/**
 * <p>
 * FileHelper
 * </p>
 * <p>
 * 文件助手，用来获取文件相关的支持，与配置池项配合，实现3级的配置体系
 * </p>
 * 
 * @author 周华彬(zhouhuabin@ctfo.com)
 * @version 0.0.0
 *          <table style="border:1px solid gray;">
 *          <tr>
 *          <th width="100px">版本号</th>
 *          <th width="100px">动作</th>
 *          <th * width="100px">修改人</th>
 *          <th width="100px">修改时间</th>
 *          </tr>
 *          <!-- 以 Table 方式书写修改历史 -->
 *          <tr>
 *          <td>0.0.0</td>
 *          <td>创建类</td>
 *          <td>周华彬</td>
 *          <td>2008-7-14 下午02:24:05</td>
 *          </tr>
 *          <tr>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          </tr>
 *          </table>
 */
public class FileHelper {


	/** 日志记录器 */
	protected static Logger log = CommonLogFactory.getLog();
	/** 项目下存放多个模块的模块文件夹名称，例如pro1/modules/mod1的modules部分 */
	public static final String CONST_DEFAULT_CHARSET = Charset.defaultCharset().name();

	/** 当前用户工作路径user.dir，在开发工具下运行为当前项目路径 */
	private static String userDir=".";

	/**
	 * 初始化文件
	 */
	public static void init() {
	}

	/**
	 * 文件转换为字符串
	 * 
	 * @param file
	 * @param charSet
	 *            文件的字符集
	 * @return
	 */
	public static String fileToString(File file, String charSet) {
		StringBuilder sb = new StringBuilder();
		try {
			InputStream is = new FileInputStream(file);
			BufferedReader br = new BufferedReader(new InputStreamReader(is,
					charSet));
			String line = "";
			while ((line = br.readLine()) != null) {
				sb.append(line).append("\r\n");
			}
			br.close();
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
			sb.append("error");
			return null;
		}
		return sb.toString();
	}
	/**
	 * 将url的资源下载到输出流中 
	 * @param url_str	要下载的资源文件
	 * @param output	要输出的流对象
	 * @return
	 */
	public static boolean url2Stream(String url_str, OutputStream output) {
		InputStream is = null;
		try {
			URL url = new URL(url_str);
			URLConnection c = url.openConnection();
			c.setConnectTimeout(30 * 1000);
			c.setReadTimeout(300 * 1000);
			c.connect();
			is = c.getInputStream();
			byte[] bitData = new byte[1024];
			try {
				int len,totalLen=0;
				while ((len = is.read(bitData)) > 0) {
					output.write(bitData, 0, len);
					totalLen += len;
				}
				log.info("下载url成功,大小:"+totalLen);
			} catch (IOException e) {
				log.error("读取数据文件失败！msg=" + e.getLocalizedMessage());
			}
			
		} catch (Exception e) {
			log.error("下载远程URL出错! url=" + url_str + " " + e.getMessage());
		} finally {
			try {
				if (is != null)
					is.close();
			} catch (IOException e) {
				log.error("关闭对象时出错! cityCode=" + url_str + e.getMessage());
				return false;
			}
		}
		return true;
	}
	/**
	 * 将url保存为本地文件 
	 * @param urlName	url地址
	 * @param fileName  本地文件名
	 * @return
	 */
	public static boolean url2file(String urlName, String fileName) {
		try {
			URL url = new URL(urlName);
			java.io.BufferedInputStream bis = new BufferedInputStream(
					url.openStream());
			byte[] bytes = new byte[1024];
			OutputStream bos = new FileOutputStream(new File(fileName));
			int len;
			while ((len = bis.read(bytes)) > 0) {
				bos.write(bytes, 0, len);
			}
			bis.close();
			bos.flush();
			bos.close();

		} catch (Exception e) {
			log.error("保存远程url到本地文件出错,msg="+e.getLocalizedMessage(),e);
			return false;
		}
		return true;
	}

	/**
	 * 判断文件对象是否有效 
	 * @param file
	 * @return
	 */
	public static boolean validFile(File file){
		if(file == null) return false;
		return file.exists();
	}
	
	/**
	 * 根据文件对象创建缓冲读 
	 * @param file
	 * @return
	 * 字段 userDir 获取函数
	 * 
	 * @return the userDir : String
	 */
	public static String getUserDir() {
		return userDir;
	}

	/**
	 * 字段 userDir 设置函数 : String
	 * 
	 * @param userDir
	 *            the userDir to set
	 */
	public static void setUserDir(String userDir) {
		FileHelper.userDir = userDir;
	}

	/**
	 * 根据文件路径创建读入流 
	 * @param file 本地文件路况
	 * @param charSet	字符集
	 * @return
	 */
	public static BufferedReader createBufferReaderByFile(File file,String charSet){
		BufferedReader reader = null;
		try {
			InputStream stream = new FileInputStream(file); 
			reader = new BufferedReader(new InputStreamReader(stream,charSet));
		} catch (FileNotFoundException e) {
			log.error("获取文件流出错,msg="+file.getName(), e);
		} catch (UnsupportedEncodingException e) {
			log.error("获取文件流出错,msg="+file.getName(), e);
		} 
		return reader;
	}
	/**
	 * 根据路径读取文件流 
	 * @param dataPath	文件路况
	 * @param timeout	http时，超时时间毫秒值
	 * @param charSet	文件的字符集
	 * @return BufferedReader 缓冲读
	 */
	public static BufferedReader createBufferedReader(String dataPath, int timeout,String charSet){
		BufferedReader bufferedReader = null;
		InputStream inputStream = null;
		if(dataPath.toLowerCase().startsWith("http:")){
			URL url = null;
			HttpURLConnection httpUrl = null;
			try{
				url = new URL(dataPath);
				httpUrl = (HttpURLConnection) url.openConnection();
				httpUrl.setConnectTimeout(timeout);
				httpUrl.setReadTimeout(timeout);
				inputStream = httpUrl.getInputStream();
				bufferedReader = new BufferedReader(new InputStreamReader(inputStream,charSet));
			}catch(Exception e){
				log.error("读取远程文件出错,url="+dataPath+",msg="+e.getLocalizedMessage());
				return null;
			}
		}else{
			try{
				File file = new File(dataPath);
				bufferedReader = createBufferReaderByFile(file,charSet);
			}catch(Exception e){
				log.error("读取本地文件出错,path="+dataPath, e);
				return null;
			}
		}
		return bufferedReader;
	}
	
	/**
	 * 创建缓冲流写入 
	 * @param fileName	本地文件路径名，自动创建目录
	 * @param append	如果文件存在，是否追加
	 * @return	写入器对象
	 * @throws IOException
	 */
	public static BufferedWriter createBufferedWriter(String fileName,boolean append) throws IOException{
		FileHelper.makePathByFileName(fileName);
		File file=new File(fileName);
//		FileOutputStream fo = new FileOutputStream(file, append);
		BufferedWriter bw = null;
		try {
			bw = new BufferedWriter(new FileWriter(file,append));
		} catch (IOException e) {
			log.error("创建写入缓冲流失败,msg="+e.getLocalizedMessage(), e);
			throw e;
		}
		return  bw;
	}
	/**
	 * 创建文件写入器 
	 * @param fileName	本地文件路径名，自动创建目录
	 * @param append	如果文件存在，是否追加
	 * @return	写入器对象
	 * @throws IOException
	 */
	public static FileWriter createFileWriter(String fileName,boolean append) throws IOException{
		FileHelper.makePathByFileName(fileName);
		File file=new File(fileName);
//		FileOutputStream fo = new FileOutputStream(file, append);
		FileWriter fw = null;
		try {
			fw = new FileWriter(file,append);
		} catch (IOException e) {
			log.error("创建写入流失败,msg="+e.getLocalizedMessage(), e);
			throw e;
		}
		return  fw;
	}
	/**
	 * 根据相对路径获得实际路径 
	 * @param relative
	 * @return
	 */
	public static String getRealPathByRelative(String relative){
		File directory = new File(relative);
		File newPath = null;
		String currentDir=null;
		try {
			newPath = new File(directory.getCanonicalPath());
			newPath.mkdir();
		} catch (Exception exp) {
			log.error("获取文件路径出错,path="+relative, exp);
		}
		if (newPath != null)
			currentDir = newPath.getPath() + File.separator;
		else
			currentDir = "\\";
		return currentDir;
	}
	/**
	 * 根据文件名创建上级目录结构 
	 * @param fileName
	 * @return
	 */
	public static String makePathByFileName(String fileName){
		File directory = new File(fileName);
		File newPath = null;
		String currentDir=null;
		try {
			newPath = new File(directory.getParent());
			newPath.mkdirs();
		} catch (Exception exp) {
			log.error("获取文件路径出错,path="+fileName, exp);
		}
		if (newPath != null)
			currentDir = newPath.getPath() + File.separator;
		else
			currentDir = "\\";
		return currentDir;
	}
	
	/**
	 * 将输入流转换为字节数组 
	 * @param inStream
	 * @return
	 * @throws IOException
	 */
	public static byte[] inputStreamToByte(InputStream inStream) throws IOException
	{
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
		byte[] buff = new byte[1024];
		int rc = 0;
		while ((rc = inStream.read(buff, 0, buff.length)) > 0) {
			swapStream.write(buff, 0, rc);
		}
		return swapStream.toByteArray();
	}
	
	/**
	 * 文件转换为字符串
	 * 
	 * @param file
	 * @param charSet
	 *            文件的字符集
	 * @return
	 */

	public static void main(String[] args) {
		File file = new File("D:\\var\\rtti\\log\\Monitor_Process_beijing.log");
		String content = fileToString(file, "GBK");
		System.out.println("读取后的内容是:" + content);
		System.out.println("获取实际路径1是:" +getRealPathByRelative("."));
		System.out.println("获取实际路径2是:" +getRealPathByRelative("汉字目录试试"));
	}
}
